package com.quectel.business.dms.application;

import cn.hutool.core.util.StrUtil;
import com.quectel.constant.global.annotation.ApplicationUniqueFlag;
import com.quectel.util.common.JacksonUtils;
import lombok.*;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 接入方式
 *
 * @author rananxin
 * @email: ryan.ran@quectel.com
 * @date 2021/11/18 2:54 下午
 */
@Data
public class ApplicationAccessConf {


    public interface BaseTemplate {
    }

    public static <T extends BaseTemplate> T parseExtStr(Class<T> tClass, String jsonStr) {
        if (StringUtils.isBlank(jsonStr)) {
            return null;
        }
        return JacksonUtils.parse(jsonStr, tClass);
    }

    public static <T extends BaseTemplate> T parseExtStr(String code, String jsonStr) {
        return parseExtStr(getEnumByCode(code), jsonStr);
    }

    public static <T extends BaseTemplate> T parseExtStr(ConfCodeEnum confCodeEnum, String jsonStr) {
        if (confCodeEnum == null) {
            return null;
        }
        Class<?>[] declaredClasses = ApplicationAccessConf.class.getDeclaredClasses();
        for (Class<?> declaredClass : declaredClasses) {
            if (declaredClass.getSimpleName().endsWith(StrUtil.upperFirst(confCodeEnum.getCode()))) {
                JacksonUtils.parse(jsonStr, declaredClass);
            }
        }
        return null;
    }

    public static ConfCodeEnum getEnumByCode(String code) {
        for (ConfCodeEnum value : ConfCodeEnum.values()) {
            if (value.code == code) {
                return value;
            }
        }
        return null;
    }

    public static List<String> getConfigUniqueFlag(String code) {
        Class<?>[] declaredClasses = ApplicationAccessConf.class.getDeclaredClasses();
        List<String> fieldNames = new ArrayList<>();

        for (Class<?> declaredClass : declaredClasses) {
            if (declaredClass.getSimpleName().endsWith(StrUtil.upperFirst(code))) {
                for (Field declaredField : declaredClass.getDeclaredFields()) {
                    ApplicationUniqueFlag annotation = declaredField.getAnnotation(ApplicationUniqueFlag.class);
                    if (annotation != null) {
                        fieldNames.add(declaredField.getName());
                    }
                }
                break;
            }
        }

        return fieldNames;
    }


    @Data
    public static class TemplateOfSimulationConf implements BaseTemplate {

        @ApplicationUniqueFlag
        private String url;

        @ApplicationUniqueFlag
        private String accessKey;

        private String accessSecret;

    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class TemplateOfEmqConf implements BaseTemplate {

        @ApplicationUniqueFlag
        private String appId;

        private String appSecret;
    }

    @Data
    public static class TemplateOfHik8700Conf implements BaseTemplate {

        @ApplicationUniqueFlag
        private String host;

        @ApplicationUniqueFlag
        private String key;

        private String secret;


    }

    @Data
    public static class TemplateOfHikIscConf implements BaseTemplate {

        @ApplicationUniqueFlag
        private String host;

        @ApplicationUniqueFlag
        private String ak;

        private String sk;

        private List<NvrItem> nvrList = new ArrayList<>();

        @Data
        public static class NvrItem {

            private String host;

            private String nvrUser;

            private String nvrPwd;
        }

        public NvrItem filterByHost(String host) {
            if (this.nvrList == null || host == null) {
                return null;
            }
            return this.nvrList
                    .stream()
                    .filter(v -> Objects.equals(host, v.getHost()))
                    .findAny()
                    .orElse(null);

        }


    }

    @Data
    public static class TemplateOfDahua9100Conf implements BaseTemplate {


        @ApplicationUniqueFlag
        private String ip;

        @ApplicationUniqueFlag
        private String username;

        private String password;

    }

    @Data
    public static class TemplateOfKuangshiBoxConf implements BaseTemplate {


        @ApplicationUniqueFlag
        private String baseUrl;

        private String username;

        private String password;

    }

    @Data
    public static class TemplateOfQuecAttendanceConf implements BaseTemplate {

        @ApplicationUniqueFlag
        private String baseUrl;

        @ApplicationUniqueFlag
        private String appKey;

        private String appSecret;

    }


    @AllArgsConstructor
    public enum ConfCodeEnum {
        /**
         * EMQ网关
         */
        EMQ("EmqConf"),
        /**
         * 海康isc
         */
        HIK_ISC("HikIscConf"),
        /**
         * 海康8700
         */
        HIK8700("Hik8700Conf"),
        /**
         * 大华9100平台
         */
        DAHUA_9100("Dahua9100Conf"),

        /**
         * 矿视盒子
         */
        KUANGSHI("KuangshiBoxConf"),

        /**
         * 移远门禁
         */
        QUEC_ATTENDANCE("QuecAttendanceConf");

        @Getter
        private String code;
    }
}
